---
title: 开始使用
icon: Album
---

## 安装

...

## 使用

<Tabs items={["Vite", "Rollup", "Webpack", "Rspack", "Nuxt", "Vue CLI", "Quasar", "esbuild", "Astro"]}>
  <Tab>
    ```ts title="vite.config.ts"
    import OperatorOverload from "@graphif/unplugin-operator-overload/vite";

    export default defineConfig({
      plugins: [
        OperatorOverload({
          /* options */
        }),
      ],
    });
    ```

  </Tab>

  <Tab>
    ```ts title="rollup.config.js"
    import OperatorOverload from "@graphif/unplugin-operator-overload/rollup";

    export default {
      plugins: [
        OperatorOverload({
          /* options */
        }),
        // other plugins
      ],
    };
    ```

  </Tab>

  <Tab>
    ```ts title="webpack.config.js"
    module.exports = {
      /* ... */
      plugins: [
        require("@graphif/unplugin-operator-overload/webpack").default({
          /* options */
        }),
      ],
    };
    ```
  </Tab>

  <Tab>
    ```ts title="rspack.config.js"
    module.exports = {
      /* ... */
      plugins: [
        require("@graphif/unplugin-operator-overload/rspack").default({
          /* options */
        }),
      ],
    };
    ```
  </Tab>

  <Tab>
    ```ts title="nuxt.config.js"
    export default defineNuxtConfig({
      modules: [
        [
          "@graphif/unplugin-operator-overload/nuxt",
          {
            /* options */
          },
        ],
      ],
    });
    ```
  </Tab>

  <Tab>
    ```ts title="vue.config.js"
    module.exports = {
      /* ... */
      plugins: [
        require("@graphif/unplugin-operator-overload/webpack").default({
          /* options */
        }),
      ],
    };
    ```

    You can also rename the Vue configuration file to `vue.config.mjs` and use static import syntax (you should use latest `@vue/cli-service ^5.0.8`):

    ```ts title="vue.config.mjs"
    import OperatorOverload from "@graphif/unplugin-operator-overload/webpack";

    export default {
      configureWebpack: {
        plugins: [
          OperatorOverload({
            /* options */
          }),
        ],
      },
    };
    ```

  </Tab>

  <Tab>
    **Vite:**
    ```ts title="vite.config.js"
    import OperatorOverload from "@graphif/unplugin-operator-overload/vite";
    import { defineConfig } from "vite";

    export default defineConfig({
      plugins: [
        OperatorOverload({
          /* options */
        }),
      ],
    });
    ```

    **Webpack:**
    ```ts title="quasar.conf.js"
    const OperatorOverloadPlugin = require("@graphif/unplugin-operator-overload/webpack").default;

    module.exports = {
      build: {
        chainWebpack(chain) {
          chain.plugin("@graphif/unplugin-operator-overload").use(
            OperatorOverloadPlugin({
              /* options */
            }),
          );
        },
      },
    };
    ```

  </Tab>

  <Tab>
    ```ts title="esbuild.config.js"
    import { build } from "esbuild";
    import OperatorOverload from "@graphif/unplugin-operator-overload/esbuild";

    build({
      /* ... */
      plugins: [
        OperatorOverload({
          /* options */
        }),
      ],
    });
    ```

  </Tab>

  <Tab>
    ```ts title="astro.config.mjs"
    import OperatorOverload from "@graphif/unplugin-operator-overload/astro";

    export default defineConfig({
      integrations: [
        OperatorOverload({
          /* options */
        }),
      ],
    });
    ```

  </Tab>
</Tabs>

### 修补 TypeScript

这一步是防止 TypeScript 报错 `Operator X cannot be applied to types Y and Z. (ts 2365)`

如果下面没有你使用的 TypeScript 版本，可以手动写 patch

<Tabs items={["5.9.2"]}>
  <Tab>
    ```diff
    diff --git a/lib/_tsc.js b/lib/_tsc.js
    index 11ab5ff444ede75f643b3df775438d35d56fb9bd..430031522df8728d0b0a1179b24de969681999b1 100644
    --- a/lib/_tsc.js
    +++ b/lib/_tsc.js
    @@ -80238,16 +80238,6 @@ function createTypeChecker(host) {
            [effectiveLeft, effectiveRight] = getBaseTypesIfUnrelated(leftType, rightType, isRelated);
          }
          const [leftStr, rightStr] = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight);
    -      if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) {
    -        errorAndMaybeSuggestAwait(
    -          errNode,
    -          wouldWorkWithAwait,
    -          Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2,
    -          tokenToString(operatorToken.kind),
    -          leftStr,
    -          rightStr
    -        );
    -      }
        }
        function tryGiveBetterPrimaryError(errNode, maybeMissingAwait, leftStr, rightStr) {
          switch (operatorToken.kind) {
    diff --git a/lib/typescript.js b/lib/typescript.js
    index 2643aa12aa6497ca0b90ecd99b202f37ea0e6330..7cf10bb62ba73a3dbd5a4009b07a0ba5641d0516 100644
    --- a/lib/typescript.js
    +++ b/lib/typescript.js
    @@ -84849,16 +84849,6 @@ function createTypeChecker(host) {
            [effectiveLeft, effectiveRight] = getBaseTypesIfUnrelated(leftType, rightType, isRelated);
          }
          const [leftStr, rightStr] = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight);
    -      if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) {
    -        errorAndMaybeSuggestAwait(
    -          errNode,
    -          wouldWorkWithAwait,
    -          Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2,
    -          tokenToString(operatorToken.kind),
    -          leftStr,
    -          rightStr
    -        );
    -      }
        }
        function tryGiveBetterPrimaryError(errNode, maybeMissingAwait, leftStr, rightStr) {
          switch (operatorToken.kind) {
    ```

  </Tab>
</Tabs>

### 配置 LSP 服务器使用工作区中的 TypeScript

让上一步中的补丁生效

<Tabs items={["Zed", "VSCode"]}>
  <Tab>
    ```json title=".zed/settings.json"
    {
      "lsp": {
        "vtsls": {
          "settings": {
            "typescript": {
              "tsdk": "node_modules/typescript/lib"
            }
          }
        }
      }
    }
    ```

  </Tab>

  <Tab>
    ```json title=".vscode/settings.json"
    {
      "typescript.tsdk": "node_modules/typescript/lib"
    }
    ```

  </Tab>
</Tabs>

### 定义方法

和 Python 一样，使用 `__add__`、`__sub__` 等魔法方法来定义运算符重载：

```ts title="example.ts"
class Vector {
  constructor(
    public x: number,
    public y: number,
  ) {}
  __add__(other: Vector) {
    return new Vector(this.x + other.x, this.y + other.y);
  }
  __sub__(other: Vector) {
    return new Vector(this.x - other.x, this.y - other.y);
  }
  __mul__(scalar: number) {
    return new Vector(this.x * scalar, this.y * scalar);
  }
  __div__(scalar: number) {
    return new Vector(this.x / scalar, this.y / scalar);
  }
}
```
